// Copyright (c) 2024 CHANGLEI. All rights reserved.

import 'package:charts_grasp/src/chart/chart_series/series_renderer_properties.dart';
import 'package:charts_grasp/src/chart/chart_series/xy_data_series.dart';
import 'package:charts_grasp/src/chart/common/cartesian_state_properties.dart';
import 'package:charts_grasp/src/chart/common/data_label_renderer.dart';
import 'package:charts_grasp/src/chart/utils/enum.dart';
import 'package:charts_grasp/src/circular_chart/renderer/circular_chart_annotation.dart';
import 'package:charts_grasp/src/circular_chart/utils/enum.dart';
import 'package:charts_grasp/src/common/utils/enum.dart';
import 'package:charts_grasp/src/common/utils/typedef.dart';
import 'package:flutter/material.dart';

@immutable
class DataLabelSettings {
  const DataLabelSettings({
    this.alignment = ChartAlignment.center,
    this.color,
    this.textStyle,
    this.margin = const EdgeInsets.fromLTRB(5, 5, 5, 5),
    this.opacity = 1,
    this.labelAlignment = ChartDataLabelAlignment.auto,
    this.borderRadius = 5,
    this.isVisible = false,
    this.angle = 0,
    this.builder,
    this.useSeriesColor = false,
    this.offset,
    this.showCumulativeValues = false,
    this.showZeroValue = true,
    this.borderColor = Colors.transparent,
    this.borderWidth = 0,
    this.overflowMode = OverflowMode.none,
    this.labelIntersectAction = LabelIntersectAction.shift,
    this.connectorLineSettings = const ConnectorLineSettings(),
    this.labelPosition = ChartDataLabelPosition.inside,
  });

  final ChartAlignment alignment;

  final Color? color;

  final TextStyle? textStyle;

  final EdgeInsets margin;

  final double opacity;

  final bool useSeriesColor;

  final ChartDataLabelAlignment labelAlignment;

  final double borderRadius;

  final bool isVisible;

  final int angle;

  final Color borderColor;

  final double borderWidth;

  final ChartDataLabelPosition labelPosition;

  final OverflowMode overflowMode;

  final ConnectorLineSettings connectorLineSettings;

  final LabelIntersectAction labelIntersectAction;

  final ChartWidgetBuilder<dynamic>? builder;

  final bool showCumulativeValues;

  final bool showZeroValue;

  final Offset? offset;

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (other.runtimeType != runtimeType) {
      return false;
    }

    return other is DataLabelSettings &&
        other.alignment == alignment &&
        other.color == color &&
        other.textStyle == textStyle &&
        other.margin == margin &&
        other.opacity == opacity &&
        other.labelAlignment == labelAlignment &&
        other.borderRadius == borderRadius &&
        other.isVisible == isVisible &&
        other.angle == angle &&
        other.builder == builder &&
        other.useSeriesColor == useSeriesColor &&
        other.offset == offset &&
        other.showCumulativeValues == showCumulativeValues &&
        other.showZeroValue == showZeroValue &&
        other.borderColor == borderColor &&
        other.borderWidth == borderWidth &&
        other.overflowMode == overflowMode &&
        other.labelIntersectAction == labelIntersectAction &&
        other.connectorLineSettings == connectorLineSettings &&
        other.labelPosition == labelPosition;
  }

  @override
  int get hashCode {
    final List<Object?> values = <Object?>[
      alignment,
      color,
      textStyle,
      margin,
      opacity,
      labelAlignment,
      borderRadius,
      isVisible,
      angle,
      builder,
      useSeriesColor,
      offset,
      showCumulativeValues,
      showZeroValue,
      borderColor,
      borderWidth,
      overflowMode,
      labelIntersectAction,
      connectorLineSettings,
      labelPosition,
    ];
    return Object.hashAll(values);
  }
}

class DataLabelSettingsRenderer {
  DataLabelSettingsRenderer(this.dataLabelSettings) {
    angle = dataLabelSettings.angle;
    offset = dataLabelSettings.offset;
    color = dataLabelSettings.color;
  }

  final DataLabelSettings dataLabelSettings;

  Color? color;

  TextStyle? textStyle;

  TextStyle? originalStyle;

  late int angle;

  Offset? offset;

  bool isCustomTextColor = false;

  void renderDataLabel(
      CartesianStateProperties stateProperties,
      SeriesRendererDetails seriesRendererDetails,
      CartesianChartPoint<dynamic> point,
      Animation<double> animationController,
      Canvas canvas,
      int labelIndex,
      DataLabelSettingsRenderer dataLabelSettingsRenderer,) {
    calculateDataLabelPosition(
        seriesRendererDetails, point, labelIndex, stateProperties, dataLabelSettingsRenderer, animationController,);
    drawDataLabel(canvas, seriesRendererDetails, stateProperties, dataLabelSettings, point, labelIndex,
        animationController, dataLabelSettingsRenderer,);
  }
}
